/**
 * @file	IPluginSystemImp.cpp
 * @author  rectcao <caobiao@gmail.com>
 */

#include "IDllImp.hpp"
namespace foundation
{

IDllImp::IDllImp(const char* pPluginName)
	:m_pluginName(pPluginName)
{

}

IDllImp::~IDllImp()
{

}

const char* IDllImp::GetPluginName()
{
	return m_pluginName.c_str();
}

bool IDllImp::Load()
{
	m_handleInst = (DYNLIB_HANDLE)DYNLIB_LOAD(m_pluginName.c_str());
	if (!m_handleInst)
		return false;

	if (!_Initialize())
		return false;

	return true;
}

bool IDllImp::UnLoad()
{
	if (!_Shutdown())
		return false;

	return DYNLIB_UNLOAD(m_handleInst);
}

void* IDllImp::GetSymbol(const char* pName) const
{
	return (void*)DYNLIB_GETSYM(m_handleInst, pName);
}

bool IDllImp::_Initialize()
{
	DLL_START_PLUGIN pStartFunc = (DLL_START_PLUGIN)GetSymbol("startPlugin");

	if (pStartFunc)
	{
		pStartFunc();
		return true;
	}
	return false;
}

bool IDllImp::_Shutdown()
{
	return true;
}

IDllManagerImp::IDllManagerImp()
{

}

IDllManagerImp::~IDllManagerImp()
{
	_ReleaseAll();
}

void	IDllManagerImp::_ReleaseAll()
{
	for (stdext::hash_map<std::string, IDll*>::iterator it = m_hmPlugins.begin();
		it != m_hmPlugins.end();it++)
	{
		IDll *pPlugin =  (IDll *)it->second;
		pPlugin->UnLoad();

		delete pPlugin;
	}
	m_hmPlugins.clear();
}

IDll* IDllManagerImp::Load(const char* pPluginName)
{
	stdext::hash_map<std::string, IDll*>::iterator it = m_hmPlugins.find(pPluginName);
	if (it  != m_hmPlugins.end())
	{
		IDll *pPlugin = (IDll*)it->second;;
		return pPlugin;
	}

	IDll *pPlugin = new IDllImp(pPluginName);
	if (pPlugin->Load())
	{
		m_hmPlugins[pPluginName] = pPlugin;
		return pPlugin;
	}
	return 0;
}

bool IDllManagerImp::Unload(const char* pPluginName)
{
	stdext::hash_map<std::string, IDll*>::iterator it = m_hmPlugins.find(pPluginName);
	if (it  != m_hmPlugins.end())
	{
		IDll *pPlugin = (IDll*)it->second;;
		pPlugin->UnLoad();
	}
	return 0;
}

bool IDllManagerImp::UnLoads()
{
	return true;
}
}